// <editor-fold defaultstate="collapsed" desc="GNU GPLv3 Header">
/*
 * File:   ChunkFormat.java
 *
 * Copyright (C) 2013 Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * Copyright (C) 2013 David Megias Jimenez <dmegias@uoc.edu>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
// </editor-fold>
package uoc.libwave;

// <editor-fold defaultstate="collapsed" desc="imports">
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
// </editor-fold>

/**
 * Class for storing a generic WAVE format chunk and, for reading and writing
 * its content in Data I/O Streams.
 *
 * @author Robert Antoni Buj Gelonch <rbuj@uoc.edu>
 * @version 1.0
 * @since 2013-08-04
 */
class ChunkFormat extends Chunk {

    /**
     * The number indicating the WAVE format category of the file.
     */
    protected short wFormatTag;
    /**
     * The number of channels represented in the waveform data, such as 1 for
     * mono or 2 for stereo.
     */
    protected short wChannels;
    /**
     * The sampling rate (in samples per second) at which each channel should
     * be played.
     */
    protected int dwSamplesPerSec;
    /**
     * The average number of bytes per second at which the waveform data should
     * be transferred. Playback software can estimate the buffer size using this
     * value.
     */
    protected int dwAvgBytesPerSec;
    /**
     * The block alignment (in bytes) of the waveform data. Playback software
     * needs to process a multiple of wBlockAlign bytes of data at a time, so
     * the value of wBlockAlign can be used for buffer alignment.
     */
    protected short wBlockAlign;

    /**
     * The wBitsPerSample field specifies the number of bits of data used to
     * represent each sample of each channel. If there are multiple channels,
     * the sample size is the same for each channel.
     */
    protected short wBitsPerSample;

    static String CHUNK_FORMAT_ID = "fmt ";

    /**
     *
     * @since 2013-08-04
     */
    ChunkFormat() {
    }

    /**
     *
     * @param formatChunkID The id of the WAVE chunk.
     * @param formatChunkSize The byte number of the WAVE chunk.
     * @param _wFormatTag The number indicating the WAVE format.
     * @param _wChannels number of channels.
     * @param _dwSamplesPerSec The sampling rate (in samples per second).
     * @param _dwAvgBytesPerSec The average number of bytes per second.
     * @param _wBlockAlign The block alignment (in bytes) of the waveform data.
     * @param _wBitsPerSample
     *
     * @since 2013-08-04
     */
    ChunkFormat(String formatChunkID, int formatChunkSize, short _wFormatTag,
            short _wChannels, int _dwSamplesPerSec, int _dwAvgBytesPerSec,
            short _wBlockAlign, short _wBitsPerSample) {
        super(formatChunkID, formatChunkSize);
        wFormatTag = _wFormatTag;
        wChannels = _wChannels;
        dwSamplesPerSec = _dwSamplesPerSec;
        dwAvgBytesPerSec = _dwAvgBytesPerSec;
        wBlockAlign = _wBlockAlign;
        wBitsPerSample = _wBitsPerSample;
    }

    /**
     *
     * @param formatChunkSize
     * @param _wFormatTag
     * @param _wChannels
     * @param _dwSamplesPerSec
     * @param _nAvgBytesPerSec
     * @param _nBlockAlign
     * @param _wBitsPerSample
     *
     * @since 2013-08-30
     */
    ChunkFormat(int formatChunkSize, short _wFormatTag, short _wChannels,
            int _dwSamplesPerSec, int _nAvgBytesPerSec, short _nBlockAlign,
            short _wBitsPerSample){
        super(CHUNK_FORMAT_ID, formatChunkSize);
        wFormatTag = _wFormatTag;
        wChannels = _wChannels;
        dwSamplesPerSec = _dwSamplesPerSec;
        dwAvgBytesPerSec = _nAvgBytesPerSec;
        wBlockAlign = _nBlockAlign;
        wBitsPerSample = _wBitsPerSample;
    }

    /**
     * Writes the WAVE format tag to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     *
     * @since 2013-08-04
     */
    protected void writeWFormatTag(DataOutputStream dos) throws IOException {
        writeShortLE(wFormatTag, dos);
    }

    /**
     * Writes the number of channels to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     *
     * @since 2013-08-04
     */
    protected void writeWChannels(DataOutputStream dos) throws IOException {
        writeShortLE(wChannels, dos);
    }

    /**
     * Writes the sampling rate to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     *
     * @since 2013-08-04
     */
    protected void writeDWSamplesPerSec(DataOutputStream dos) throws IOException {
        writeLongLE(dwSamplesPerSec, dos);
    }

    /**
     * Writes the average number of bytes per second to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     *
     * @since 2013-08-04
     */
    protected void writeDWAvgBytesPerSec(DataOutputStream dos) throws IOException {
        writeLongLE(dwAvgBytesPerSec, dos);
    }

    /**
     * Writes the block alignment to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     * 
     * @since 2013-08-04
     */
    protected void writeWBlockAlign(DataOutputStream dos) throws IOException {
        writeShortLE(wBlockAlign, dos);
    }

    /**
     * Writes the bits per sample to a DataOutputStream.
     *
     * @param dos DataOutputStream that points correctly to the underlying output
     * stream for writing data.
     * @throws IOException if an output error occurs.
     *
     * @since 2013-08-04
     */
    protected void writeWBitsPerSample(DataOutputStream dos) throws IOException {
        writeShortLE(wBitsPerSample, dos);
    }

    /**
     * Returns the value of the wFormatTag variable.
     *
     * @return The WAVE format tag.
     *
     * @since 2013-08-04
     */
    short getWFormatTag() {
        return wFormatTag;
    }

    /**
     * Returns the value of the wChannels variable.
     *
     * @return The number of channels.
     *
     * @since 2013-08-05
     */
    short getWChannels() {
        return wChannels;
    }

    /**
     * Returns the value of the wBlockAlign variable.
     *
     * @return The block align.
     *
     * @since 2013-08-07
     */
    short getWBlockAlign() {
        return wBlockAlign;
    }

    /**
     * Returns the value of the wBitsPerSample variable.
     *
     * @return The bits per sample
     *
     * @since 2013-08-04
     */
    short getWBitsPerSample() {
        return wBitsPerSample;
    }

    /**
     * Returns the value of the dwSamplesPerSec variable.
     *
     * @return The samples per second.
     *
     * @since 2013-08-27
     */
    int getDwSamplesPerSec() {
        return dwSamplesPerSec;
    }
}
